package middlewares

import (
	"GoWeb_Advanced/00_bluebell/controllers"
	"GoWeb_Advanced/00_bluebell/pkg/jwt"
	"strings"

	"github.com/gin-gonic/gin"
)

// JWTAuthMiddleware 基于 JWT 的认证中间件
func JWTAuthMiddleware() func(ctx *gin.Context) {
	return func(ctx *gin.Context) {
		//客户端携带 Token 有三种方式：1.放在请求头 2.放在请求体（Get请求没有请求体） 3.放在 URL（别人一眼就可以看见）
		//这里假设 Token 放在 Header 的 Authorization 中，并使用 Bearer 开头
		//Authorization: Bearer xxxxxxxx.xxx.xxx	/ X-TOKEN: xxx.xxx.xx
		//这里的具体实现方式要依据你的实际业务情况决定
		authHeader := ctx.Request.Header.Get("Authorization")
		if authHeader == "" {
			controllers.ResponseError(ctx, controllers.CodeNeedLogin)
			ctx.Abort()
			return
		}

		//按空格分割（切割为：Bearer 和 xxxxxxxx.xxx.xxx）
		parts := strings.SplitN(authHeader, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			controllers.ResponseError(ctx, controllers.CodeInvalidToken)
			ctx.Abort()
			return
		}

		//part[1] 是获取到的 tokenString，我们使用之前定义好的解析 JWT 的函数来解析它
		mc, err := jwt.ParseToken(parts[1])
		if err != nil {
			controllers.ResponseError(ctx, controllers.CodeInvalidToken)
			ctx.Abort()
			return
		}

		//将当前请求的 userID 信息保存到请求的上下文 ctx 上
		ctx.Set(controllers.CtxUserIDKey, mc.UserID)
		ctx.Next() //后续的处理请求的函数中可以用过 ctx.Get(CtxUserIDKey)来获取当前请求的用户信息
	}
}
